package com.qqtech.qquan.user.controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.qqtech.admin.context.AdminPage;
import com.qqtech.core.common.enums.YesNoEnum;
import com.qqtech.core.common.util.StringUtil;
import com.qqtech.core.frame.model.PageKit;
import com.qqtech.core.frame.model.PageOrder;
import com.qqtech.core.frame.model.Result;
import com.qqtech.core.frame.service.BaseService;
import com.qqtech.qquan.community.model.CommunityMessageVo;
import com.qqtech.qquan.community.service.CommunityMessageService;
import com.qqtech.qquan.coupon.model.CouponUserVo;
import com.qqtech.qquan.coupon.service.CouponUserService;
import com.qqtech.qquan.order.enums.OrderBaseOrderStatusDictEnum;
import com.qqtech.qquan.order.enums.OrderBaseOrderTypeDictEnum;
import com.qqtech.qquan.order.model.OrderBaseQuery;
import com.qqtech.qquan.order.model.OrderBaseVo;
import com.qqtech.qquan.order.model.OrderDelivery;
import com.qqtech.qquan.order.service.OrderBaseService;
import com.qqtech.qquan.order.service.OrderDeliveryService;
import com.qqtech.qquan.push.service.PushBizzService;
import com.qqtech.qquan.sys.controller.BaseAdminController;
import com.qqtech.qquan.sys.enums.SysConst;
import com.qqtech.qquan.sys.model.SysParam;
import com.qqtech.qquan.sys.service.SysParamService;
import com.qqtech.qquan.user.enums.UserMoneyLogTypeDictEnum;
import com.qqtech.qquan.user.model.UserBase;
import com.qqtech.qquan.user.model.UserBaseConfig;
import com.qqtech.qquan.user.model.UserBaseQuery;
import com.qqtech.qquan.user.model.UserBaseVo;
import com.qqtech.qquan.user.model.UserLogin;
import com.qqtech.qquan.user.model.UserMoneyLogVo;
import com.qqtech.qquan.user.model.UserValueVo;
import com.qqtech.qquan.user.service.UserBaseService;
import com.qqtech.qquan.user.service.UserLoginService;
import com.qqtech.qquan.user.service.UserMoneyLogService;
import com.qqtech.qquan.user.service.UserValueService;
import com.qqtech.qquan.util.ExcelUtil;

@Controller
@RequestMapping(value = "/user/base")
public class UserBaseController extends BaseAdminController {

	@Resource
	private UserBaseService userBaseService;

	@Resource
	private OrderBaseService orderBaseService;

	@Resource
	private OrderDeliveryService orderDeliveryService;

	@Resource
	private UserLoginService userLoginService;

	@Resource
	private PushBizzService pushBizzService;
	@Resource
	private SysParamService sysParamService;
	@Resource
	private UserMoneyLogService userMoneyLogService;
	@Resource
	private CommunityMessageService communityMessageService;
	@Resource
	private UserValueService userValueService;
	@Resource
	private CouponUserService couponUserService;

	@Override
	protected BaseService<UserBase> getBaseService() {
		return userBaseService;
	}

	@RequestMapping(value = "/money", method = RequestMethod.GET)
	public String money(Model model) {
		return "/user/base/userbase-money";
	}

	@RequestMapping(value = "/list", method = RequestMethod.GET)
	public String list(Model model) {
		return "/user/base/userbase-list";
	}

	@RequestMapping(value = "/list", method = RequestMethod.POST)
	@ResponseBody
	public AdminPage list(UserBaseQuery query, HttpServletRequest request, HttpServletResponse response) {
		AdminPage adminPage = new AdminPage();
		String rows = (String) request.getParameter("rows"); // 每页条数
		query.setSize(Integer.valueOf(rows));
		PageOrder pageOrder = null;
		if (StringUtil.isNotBlank(query.getSortField()) && StringUtil.isNotBlank(query.getSortDirection())) {
			if (query.getSortDirection().equalsIgnoreCase("ASC")) {
				pageOrder = new PageOrder(Direction.ASC, query.getSortField());
			} else {
				pageOrder = new PageOrder(Direction.DESC, query.getSortField());
			}
		} else {
			pageOrder = new PageOrder(Direction.DESC, "id");
		}
		Pageable pageKit = new PageKit(query.getPage(), query.getSize(), pageOrder);
		Page<UserBaseVo> page = userBaseService.queryPageList4Admin(query, pageKit);
		List<UserBaseVo> userBaseVoList = page.getContent();
		userInfoExtend4List(userBaseVoList);
		// for (UserBaseVo userVo : userBaseVoList) {
		// userInfoExtend(userVo);
		// }
		adminPage.setRows(userBaseVoList);
		adminPage.setTotal(Integer.valueOf(page.getTotalElements() + ""));
		return adminPage;
	}

	/**
	 * 社区住户认证
	 * 
	 * @param userId
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/authCommunity", method = RequestMethod.GET)
	public String authCommunity(Integer userId, Model model) {
		OrderBaseQuery orderBaseQuery = new OrderBaseQuery();
		Pageable pageKit = new PageKit(1, 10, new PageOrder(Direction.DESC, "id"));
		orderBaseQuery.setBuyerId(userId);
		orderBaseQuery.setOrderStatus(OrderBaseOrderStatusDictEnum.COMPLETED.getCode());
		orderBaseQuery.setOrderType(OrderBaseOrderTypeDictEnum.DELIVERY.getCode());
		List<OrderBaseVo> substituteList = orderBaseService.queryList(orderBaseQuery, pageKit);
		getAddress(substituteList);
		model.addAttribute("substituteList", substituteList);

		orderBaseQuery.setOrderType(OrderBaseOrderTypeDictEnum.QUANMALL.getCode());
		List<OrderBaseVo> mallList = orderBaseService.queryList(orderBaseQuery, pageKit);
		getAddress(mallList);
		model.addAttribute("mallList", mallList);

		model.addAttribute("userId", userId);
		return "/user/base/communityAuth-detail";
	}

	private void getAddress(List<OrderBaseVo> list) {
		OrderDelivery orderDelivery;
		for (OrderBaseVo orderBaseVo : list) {
			orderDelivery = orderDeliveryService.getByOrderNo(orderBaseVo.getOrderNo());
			if (null != orderDelivery) {
				orderBaseVo.setConsignee(orderDelivery.getConsignee());
				orderBaseVo.setAddress(orderDelivery.getAddress());
				orderBaseVo.setPhone(orderDelivery.getPhone());
			}
		}
	}

	/**
	 * 社区住户认证通过
	 * 
	 * @param userId
	 * @return
	 */
	@RequestMapping(value = "/passAuthCommunity", method = RequestMethod.POST)
	@ResponseBody
	public Result passAuthCommunity(Integer userId) {
		Result ret = new Result();
		UserLogin userLogin = new UserLogin();
		userLogin.setId(userId);
		userLogin.setHasCommunityAuth(YesNoEnum.YES.getCode());
		userLoginService.updateById(userLogin);
		pushBizzService.communityAuth(userId, YesNoEnum.YES);
		return ret;
	}

	/**
	 * 提供一个选择用户的页面
	 * 
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/choose", method = RequestMethod.GET)
	public String choose(Model model) {
		return "/user/base/userbase-choose";
	}

	/**
	 * 提供一个选择用户的页面
	 * 
	 * @return
	 */
	@RequestMapping(value = "/choose", method = RequestMethod.POST)
	@ResponseBody
	public AdminPage choose(UserBaseQuery query, HttpServletRequest request, HttpServletResponse response) {
		AdminPage adminPage = new AdminPage();
		String rows = (String) request.getParameter("rows"); // 每页条数
		query.setSize(Integer.valueOf(rows));
		Pageable pageKit = new PageKit(query.getPage(), query.getSize(), new PageOrder(Direction.DESC, "id"));
		Page<UserBaseVo> page = userBaseService.queryPageListByIdentity(query, pageKit);
		adminPage.setRows(page.getContent());
		adminPage.setTotal(Integer.valueOf(page.getTotalElements() + ""));
		return adminPage;
	}

	/**
	 * @param query
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "/export2Excel")
	@ResponseBody
	public Result export2Excel(UserBaseQuery query, HttpServletRequest request, HttpServletResponse response) {
		Result ret = new Result();
		PageOrder pageOrder = null;
		if (StringUtil.isNotBlank(query.getSortField()) && StringUtil.isNotBlank(query.getSortDirection())) {
			if (query.getSortDirection().equalsIgnoreCase("ASC")) {
				pageOrder = new PageOrder(Direction.ASC, query.getSortField());
			} else {
				pageOrder = new PageOrder(Direction.DESC, query.getSortField());
			}
		} else {
			pageOrder = new PageOrder(Direction.DESC, "id");
		}
		Pageable pageKit = new PageKit(1, Integer.MAX_VALUE, pageOrder);
		int count = userBaseService.queryCount4Admin(query);
		SysParam sysParam = sysParamService.getByKey(SysConst.PARAM_SYS_EXPORT_TOEXCEL_MAXROWS);
		if (sysParam != null && StringUtil.isNotBlank(sysParam.getValue())) {
			int maxExportRows = Integer.valueOf(sysParam.getValue());
			if (count > maxExportRows) {
				ret.addErr("导出数量不能超过" + maxExportRows + "行!");
				return ret;
			}
		}
		List<UserBaseVo> userVoList = userBaseService.queryList4Admin(query, pageKit);// 不分页
		userInfoExtend4List(userVoList);

		List<Map<String, Object>> list = createExcelRecord(userVoList);
		String columnNames[] = { "昵称", "社区", "性别", "帐号类型", "帐号", "发帖数", "用户评论数", "点赞数", "荣誉值", "荣誉等级", "圈币", "余额",
				"代金卷数量", "订单数量", "注册时间", "兴趣", "家乡", "美食", "行业", "学校", "娱乐", "身份认证" };// 列名
		String keys[] = { "nick", "communityName", "sexDesc", "typeDesc", "userIdentity", "talentCount",
				"totalCommentCount", "totalPraiseCount", "honorValue", "honorLevel", "quanValue", "money",
				"couponCount", "orderCount", "strNewAt", "interests", "hometown", "delicacys", "profession",
				"graduateSchool", "entertainment", "hasIdentityAuth" };// map中的key
		String fileName = "用户列表";
		ExcelUtil.ExcelSingleOutputStream(list, keys, columnNames, fileName, request, response);
		return ret;
	}

	private List<Map<String, Object>> createExcelRecord(List<UserBaseVo> userVoList) {
		List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("sheetName", "用户列表");
		listmap.add(map);
		UserBaseVo userVo = null;

		for (int j = 0; j < userVoList.size(); j++) {
			userVo = userVoList.get(j);
			Map<String, Object> mapValue = new HashMap<String, Object>();
			mapValue.put("nick", userVo.getNick());
			mapValue.put("communityName", userVo.getCommunityName());
			mapValue.put("sexDesc", userVo.getSexDesc());
			mapValue.put("typeDesc", userVo.getTypeDesc());
			mapValue.put("userIdentity", userVo.getUserIdentity());
			mapValue.put("strNewAt", userVo.getStrNewAt());
			mapValue.put("interests", userVo.getInterests());
			mapValue.put("talentCount", userVo.getTalentCount());
			mapValue.put("totalCommentCount", userVo.getTotalCommentCount());
			mapValue.put("totalPraiseCount", userVo.getTotalPraiseCount());
			mapValue.put("honorValue", userVo.getHonorValue());
			mapValue.put("honorLevel", userVo.getHonorLevel());
			mapValue.put("quanValue", userVo.getQuanValue());
			mapValue.put("money", userVo.getMoney());
			mapValue.put("couponCount", userVo.getCouponCount());
			mapValue.put("orderCount", userVo.getOrderCount());
			mapValue.put("hometown", userVo.getHometown());
			mapValue.put("delicacys", userVo.getDelicacys());
			mapValue.put("profession", userVo.getProfession());
			mapValue.put("graduateSchool", userVo.getGraduateSchool());
			mapValue.put("entertainment", userVo.getEntertainment());
			mapValue.put("hasIdentityAuth",
					userVo.getHasIdentityAuth() == null ? "" : (1 == userVo.getHasIdentityAuth() ? "已认证" : "未认证"));
			listmap.add(mapValue);
		}
		return listmap;
	}

	/**
	 * 设为官方用户
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/setIsOfficial")
	@ResponseBody
	public Result setIsOfficial(Integer id) {
		Result ret = new Result();
		UserBase user = new UserBase();
		user.setId(id);
		user.setIsOfficial(YesNoEnum.YES.getCode());
		int updateCount = userBaseService.updateById(user);
		if (updateCount != 1) {
			ret.addErr("用户-设为官方用户-失败");
		}
		return ret;
	}

	/**
	 * 设为非官方用户
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/setNotOfficial")
	@ResponseBody
	public Result setNotOfficial(Integer id) {
		Result ret = new Result();
		UserBase user = new UserBase();
		user.setId(id);
		user.setIsOfficial(YesNoEnum.NO.getCode());
		int updateCount = userBaseService.updateById(user);
		if (updateCount != 1) {
			ret.addErr("用户-设为非官方用户-失败");
		}
		return ret;
	}

	/**
	 * 设为在线客服
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/setIsOnlineService")
	@ResponseBody
	public Result setIsOnlineService(Integer id) {
		Result ret = new Result();
		UserBase user = new UserBase();
		user.setId(id);
		user.setIsOnlineService(YesNoEnum.YES.getCode());
		int updateCount = userBaseService.updateById(user);
		if (updateCount != 1) {
			ret.addErr("用户-设为在线客服-失败");
		}
		return ret;
	}

	/**
	 * 取消-在线客服
	 * 
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/setNotOnlineService")
	@ResponseBody
	public Result setNotOnlineService(Integer id) {
		Result ret = new Result();
		UserBase user = new UserBase();
		user.setId(id);
		user.setIsOnlineService(YesNoEnum.NO.getCode());
		int updateCount = userBaseService.updateById(user);
		if (updateCount != 1) {
			ret.addErr("用户-取消在线客服-失败");
		}
		return ret;
	}

	/**
	 * 圈币更新
	 * 
	 * @param userId
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/sendMoneyAdd", method = RequestMethod.GET)
	public String sendMoneyAdd(Model model, Integer userId) {
		model.addAttribute("userId", userId);
		return "/user/base/usermoney-add";
	}

	/**
	 * 创建成功
	 * 
	 * @return
	 */
	@RequestMapping(value = "/moneyAdd")
	@ResponseBody
	public Result moneyAdd(UserMoneyLogVo userMoneyLogVo) {
		Result ret = new Result();
		String tips = "(后台赠送)";
		if (StringUtil.isNotBlank(userMoneyLogVo.getRemark())) {
			tips = tips + userMoneyLogVo.getRemark();
		}
		userMoneyLogService.addMoneyToUser(userMoneyLogVo.getUserId(), userMoneyLogVo.getMoney(), tips,
				UserMoneyLogTypeDictEnum.QUAN);
		return ret;
	}

	@RequestMapping(value = "/detail", method = RequestMethod.GET)
	public String list(Integer userId, Model model) {
		UserBaseVo userVo = userBaseService.getById(userId);
		userInfoExtend4Detail(userVo);
		model.addAttribute("userBaseVo", userVo);
		return "/user/base/user-detail";

	}

	/**
	 * 用户附加信息【detail专用】
	 * 
	 * @param userVo
	 */
	private void userInfoExtend4Detail(UserBaseVo userVo) {
		userVo.setTypeDesc(userVo.getType() == null ? "" : (1 == userVo.getType() ? "手机号" : "email"));
		userVo.setSexDesc(userVo.getSex() == null ? "" : (1 == userVo.getSex() ? "男" : "女"));
		CommunityMessageVo communityMessageVo = communityMessageService.queryTotalCountByCreatorId(userVo.getId());
		if (communityMessageVo != null) {
			userVo.setTotalCommentCount(communityMessageVo.getTotalCommentCount());
			userVo.setTotalPraiseCount(communityMessageVo.getTotalPraiseCount());
			userVo.setTalentCount(communityMessageVo.getTalentCount());
		}
		UserValueVo userValueVo = userValueService.queryByUserId(userVo.getId());
		if (userValueVo != null) {
			userVo.setHonorLevel(userValueVo.getHonorLevel());
			userVo.setHonorValue(userValueVo.getHonorValue());
			userVo.setQuanValue(userValueVo.getQuanValue());
			userVo.setMoney(userValueVo.getMoney());
		}
		int couponCount = couponUserService.queryCouponCount(userVo.getId());
		userVo.setCouponCount(couponCount);
		OrderBaseQuery orderBaseQuery = new OrderBaseQuery();
		orderBaseQuery.setBuyerId(userVo.getId());
		Integer orderCount = orderBaseService.queryCount(orderBaseQuery);
		if (orderCount != null) {
			userVo.setOrderCount(orderCount);
		}
		List<UserBaseConfig> userBaseConfigProfessions = userBaseService.queryUserConfigProfession();
		Map<String, String> professionMap = new HashMap<>();
		for (UserBaseConfig userBaseConfig : userBaseConfigProfessions) {
			professionMap.put(userBaseConfig.getId().toString(), userBaseConfig.getName());
		}
		List<UserBaseConfig> userBaseConfigHometown = userBaseService.queryUserConfigHometown();
		Map<String, String> hometownMap = new HashMap<>();
		for (UserBaseConfig userBaseConfig : userBaseConfigHometown) {
			hometownMap.put(userBaseConfig.getId().toString(), userBaseConfig.getName());
		}
		userVo.setHometown(hometownMap.containsKey(userVo.getHometown()) ? hometownMap.get(userVo.getHometown())
				: userVo.getHometown());
		userVo.setProfession(professionMap.containsKey(userVo.getProfession())
				? professionMap.get(userVo.getProfession()) : userVo.getProfession());
	}

	/**
	 * 用户附加信息【list专用】
	 * 
	 * @param userVos
	 */
	private void userInfoExtend4List(List<UserBaseVo> userVos) {
		List<Integer> userIds = new ArrayList<>();
		Map<Integer, UserBaseVo> userBaseVoMap = new HashMap<>();
		List<UserBaseConfig> userBaseConfigProfessions = userBaseService.queryUserConfigProfession();
		Map<String, String> professionMap = new HashMap<>();
		for (UserBaseConfig userBaseConfig : userBaseConfigProfessions) {
			professionMap.put(userBaseConfig.getId().toString(), userBaseConfig.getName());
		}
		List<UserBaseConfig> userBaseConfigHometown = userBaseService.queryUserConfigHometown();
		Map<String, String> hometownMap = new HashMap<>();
		for (UserBaseConfig userBaseConfig : userBaseConfigHometown) {
			hometownMap.put(userBaseConfig.getId().toString(), userBaseConfig.getName());
		}
		for (UserBaseVo userBaseVo : userVos) {
			userBaseVo.setTypeDesc(userBaseVo.getType() == null ? "" : (1 == userBaseVo.getType() ? "手机号" : "email"));
			userBaseVo.setSexDesc(userBaseVo.getSex() == null ? "" : (1 == userBaseVo.getSex() ? "男" : "女"));
			userBaseVo.setHometown(hometownMap.containsKey(userBaseVo.getHometown())
					? hometownMap.get(userBaseVo.getHometown()) : userBaseVo.getHometown());
			userBaseVo.setProfession(professionMap.containsKey(userBaseVo.getProfession())
					? professionMap.get(userBaseVo.getProfession()) : userBaseVo.getProfession());
			userIds.add(userBaseVo.getId());
			userBaseVoMap.put(userBaseVo.getId(), userBaseVo);
		}
		List<CommunityMessageVo> communityMessageVos = communityMessageService.queryTotalCountByCreatorIds(userIds);
		if (!CollectionUtils.isEmpty(communityMessageVos)) {
			for (CommunityMessageVo communityMessageVo : communityMessageVos) {
				UserBaseVo userVo = userBaseVoMap.get(communityMessageVo.getCreatorId());
				if (userVo != null) {
					userVo.setTotalCommentCount(communityMessageVo.getTotalCommentCount());
					userVo.setTotalPraiseCount(communityMessageVo.getTotalPraiseCount());
					userVo.setTalentCount(communityMessageVo.getTalentCount());
				}
			}
			if (!CollectionUtils.isEmpty(communityMessageVos)) {
				for (CommunityMessageVo communityMessageVo : communityMessageVos) {
					UserBaseVo userVo = userBaseVoMap.get(communityMessageVo.getCreatorId());
					if (userVo != null) {
						userVo.setTotalCommentCount(communityMessageVo.getTotalCommentCount());
						userVo.setTotalPraiseCount(communityMessageVo.getTotalPraiseCount());
						userVo.setTalentCount(communityMessageVo.getTalentCount());
					}
				}
			}
		}
		List<UserValueVo> userValueVos = userValueService.queryByUserIds(userIds);
		if (!CollectionUtils.isEmpty(userValueVos)) {
			for (UserValueVo userValueVo : userValueVos) {
				UserBaseVo userVo = userBaseVoMap.get(userValueVo.getId());
				if (userVo != null) {
					userVo.setHonorLevel(userValueVo.getHonorLevel());
					userVo.setHonorValue(userValueVo.getHonorValue());
					userVo.setQuanValue(userValueVo.getQuanValue());
					userVo.setMoney(userValueVo.getMoney());
				}
			}
		}
		List<CouponUserVo> couponUserVos = couponUserService.queryCouponCountByUserIds(userIds);
		if (!CollectionUtils.isEmpty(couponUserVos)) {
			for (CouponUserVo couponCount : couponUserVos) {
				UserBaseVo userVo = userBaseVoMap.get(couponCount.getUserId());
				if (userVo != null) {
					userVo.setCouponCount(couponCount.getCount());
				}
			}
		}
		List<OrderBaseVo> orderBaseVos = orderBaseService.queryOrderCountByUserIds(userIds);
		if (!CollectionUtils.isEmpty(orderBaseVos)) {
			for (OrderBaseVo orderBaseVo : orderBaseVos) {
				UserBaseVo userVo = userBaseVoMap.get(orderBaseVo.getBuyerId());
				if (userVo != null) {
					userVo.setOrderCount(orderBaseVo.getUserOrderCount());
				}
			}
		}
	}
}
